﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SCRUM.Core.BusinessObjects;
using SCRUM.Core.DAO;
using System.Xml;


/// <summary>
/// Widget displays all Projects, Releases and Sprints in tree like structure.
/// User may browse the hierarchy and display all subentities for choosen entity, return to parent entity
/// and perform create, update, delete operations on all of the entities while his role is Scrum master or Porduct owner.
/// Standard team member has only read access.
/// </summary>
public partial class Widgets_TreeViewWidget_widget : WidgetBase
{

    public override string Title
    {
        get { return (string)GetLocalResourceObject("Title"); }
    }

    public override bool IsEditable
    {
        get { return false; }
    }

    /// <summary>
    /// Gets the name of the widget. It must be exactly the same as the folder that contains the widget.
    /// </summary>
    /// <value></value>
    public override string Name
    {
        get { return "TreeViewWidget"; }
    }

    /// <summary>
    /// This method works as a substitute for Page_Load. You should use this method for
    /// data binding etc. instead of Page_Load.
    /// </summary>
    public override void LoadWidget()
    {
        treeData.Visible = true;
    }

    /// <summary>
    /// Shows the edit.
    /// </summary>
    public override void ShowEdit()
    {
        DivEdit.Visible = true;
    }

    /// <summary>
    /// Hides the edit.
    /// </summary>
    public override void HideEdit()
    {
        DivEdit.Visible = false;
    }

    protected void LinkButtonSave_Click(object sender, EventArgs e)
    {
        //save config
    }

    protected void Node_Populate(object sender, TreeNodeEventArgs e)
    {
        {
            if (e.Node.ChildNodes.Count == 0)
            {
                switch (e.Node.Depth)
                {
                    case 0:
                        fillProject(e.Node);
                        break;
                    case 1:
                        fillReleasesForProject(e.Node);
                        break;
                    case 2:
                        fillSprintsForRelease(e.Node);
                        break;
                }
            }
        }
    }

    private void fillProject(TreeNode node)
    {
        foreach (Project row in DAOProject.GetAllProjects())
        {
            createSubNode(node, row.Name, row.ID.ToString(), (string)GetLocalResourceObject("Project"));
        }
    }

    private void fillReleasesForProject(TreeNode node)
    {
        string projectID = node.Value;

        IList<Release> releases = DAORelease.GetAllReleasesForProject(System.Convert.ToInt32(projectID));
        foreach (Release row in releases)
        {
            createSubNode(node, row.Name, row.ID.ToString(), (string)GetLocalResourceObject("Release"));
        }
    }

    private void fillSprintsForRelease(TreeNode node)
    {
        string sprintID = node.Value;

        IList<Sprint> sprints = DAOSprint.GetAllSprintsForRelease(System.Convert.ToInt32(sprintID));
        foreach (Sprint row in sprints)
        {
            createSubNode(node, row.Name, row.ID.ToString(), (string)GetLocalResourceObject("Sprint"));
        }
    }

    private TreeNode createSubNode(TreeNode parent, String name, String id, string type)
    {
        TreeNode newNode = new TreeNode(name, id);
        newNode.PopulateOnDemand = true;
        newNode.SelectAction = TreeNodeSelectAction.Select;
        newNode.ToolTip = type;
        parent.ChildNodes.Add(newNode);
        return newNode;
    }

    /// <summary>
    /// Handle click on data in tree and shows details
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void treeData_SelectedNodeChanged(object sender, EventArgs e)
    {
        if (treeData.SelectedNode == null)
        {
            return;
        }
        hideDetails();
        AddNewBtn.Visible = true;
        switch (treeData.SelectedNode.Depth)
        {
            case 0: 
                {
                    AddNewBtn.Text = (string)GetLocalResourceObject("AddProject");
                    OkDiv.Visible = false;
                    return;
                }
            case 1:
                {
                    AddNewBtn.Text = (string)GetLocalResourceObject("AddRelease");
                    Project proj = DAOProject.GetProjectById(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    ProjectDetails.DisplayItem(proj);
                    break;
                }
            case 2:
                {
                    AddNewBtn.Text = (string)GetLocalResourceObject("AddSprint");
                    Release rel = DAORelease.GetReleaseById(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    Project pro = DAOProject.GetProjectByReleaseID(rel.ID);
                    ReleaseDetails.AvailableSuperiorItems = DAOProject.GetAllProjects();
                    ReleaseDetails.SuperiorItemID = pro.ID;
                    ReleaseDetails.DisplayItem(rel);
                    break;
                }
            case 3:
                {
                    Sprint spr = DAOSprint.GetSprintById(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    Release re = DAORelease.GetReleaseById(System.Convert.ToInt32(treeData.SelectedNode.Parent.Value));
                    IList<Release> reles = DAORelease.GetAllReleasesForProject(System.Convert.ToInt32(treeData.SelectedNode.Parent.Parent.Value));
                    SprintDetails.SuperiorItemID = re.ID;
                    SprintDetails.AvailableSuperiorItems = reles;
                    SprintDetails.DisplayItem(spr);
                    AddNewBtn.Visible = false;
                    break;
                }
            default:
                return;
        }
        OkDiv.Visible = true;
        CreateBtn.Visible = false;
        EditBtn.Visible = true;
        DeleteBtn.Visible = true;
    }

    /// <summary>
    /// Creates new entity
    /// </summary>
    /// <param name="sender">sender</param>
    /// <param name="e">arguments</param>
    protected void AddNewSubEntityBtn_Click(object sender, EventArgs e)
    {
        if (treeData.SelectedNode == null)
        {
            return;
        }
        hideDetails();
        AddNewBtn.Visible = true;
        switch (treeData.SelectedNode.Depth)
        {
            case 2:
                {
                    Release re = DAORelease.GetReleaseById(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    IList<Release> reles = DAORelease.GetAllReleasesForProject(System.Convert.ToInt32(treeData.SelectedNode.Parent.Value));
                    SprintDetails.SuperiorItemID = re.ID;
                    SprintDetails.AvailableSuperiorItems = reles;
                    SprintDetails.SelectedItem = null;
                    break;
                }
            case 1:
                {
                    Project pro = DAOProject.GetProjectById(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    ReleaseDetails.AvailableSuperiorItems = DAOProject.GetAllProjects();
                    ReleaseDetails.SuperiorItemID = pro.ID;
                    ReleaseDetails.SelectedItem = null;
                    break;
                }
            case 0:
                {
                    ProjectDetails.SelectedItem = null;
                    OkDiv.Visible = false;
                    break;
                }
            default: 
                {
                    return;
                }
        }
        AddNewBtn.Visible = false;
        OkDiv.Visible = true;
        CreateBtn.Visible = true;
        EditBtn.Visible = false;
        DeleteBtn.Visible = false;
    }

    /// <summary>
    /// Sets visibility of all detail panels to false
    /// </summary>
    private void hideDetails()
    {
        ProjectDetails.Visible = false;
        ReleaseDetails.Visible = false;
        SprintDetails.Visible = false;
        OkDiv.Visible = false;
    }
    
    protected void CreateBtn_Click1(object sender, EventArgs e)
    {
        if (treeData.SelectedNode == null)
        {
            return;
        }
        TreeNode n;
        switch (treeData.SelectedNode.Depth)
        {
            case 2:
                {
                    Sprint spr = SprintDetails.CreateItem();
                    n = createSubNode(treeData.SelectedNode, spr.Name, spr.ID.ToString(), (string)GetLocalResourceObject("Sprint"));
                    break;
                }
            case 1:
                {
                    Release rel = ReleaseDetails.CreateItem();
                    n = createSubNode(treeData.SelectedNode, rel.Name, rel.ID.ToString(), (string)GetLocalResourceObject("Release"));
                    break;
                }
            case 0:
                {
                    Project proj = ProjectDetails.CreateItem();
                    n = createSubNode(treeData.SelectedNode, proj.Name, proj.ID.ToString(), (string)GetLocalResourceObject("Project"));
                    break;
                }
            default:
                {
                    return;
                }
        }
        treeData.DataBind();
        if (n != null)
        {
            n.Select();
            treeData_SelectedNodeChanged(new Object(), new EventArgs());
        }
    }

    protected void CancelBtn_Click(object sender, EventArgs e)
    {
        hideDetails();
        //treeData_SelectedNodeChanged(new Object(), new EventArgs());
    }

    protected void DeleteBtn_Click(object sender, EventArgs e)
    {
        if (treeData.SelectedNode == null)
        {
            return;
        }
        switch (treeData.SelectedNode.Depth)
        {
            case 3:
                {
                    int sprID = System.Convert.ToInt32(treeData.SelectedNode.Value);
                    SprintDetails.DeleteItem(DAOSprint.GetSprintById(sprID));
                    break;
                }
            case 2:
                {
                    int relID = System.Convert.ToInt32(treeData.SelectedNode.Value);
                    ReleaseDetails.DeleteItem(DAORelease.GetReleaseById(relID));
                    break;
                }
            case 1:
                {
                    int projID = System.Convert.ToInt32(treeData.SelectedNode.Value);
                    ProjectDetails.DeleteItem(DAOProject.GetProjectById(projID));
                    break;
                }
            case 0:
                {  
                    //remove all
                    return;
                }
            default:
                {
                    return;
                }
        }
        TreeNode node = treeData.SelectedNode.Parent;
        TreeNode toSelectNext;
        node.ChildNodes.Remove(treeData.SelectedNode);
        if (node.ChildNodes.Count == 0)
        {
            toSelectNext = node;
        }
        else
        {
            toSelectNext = node.ChildNodes[0];
        }
        treeData.DataBind();
        if (toSelectNext != null)
        {
            toSelectNext.Select();
            treeData_SelectedNodeChanged(new Object(), new EventArgs());
        }
    }
    protected void EditBtn_Click(object sender, EventArgs e)
    {
        if (treeData.SelectedNode == null)
        {
            return;
        }
        switch (treeData.SelectedNode.Depth)
        {
            case 3:
                {
                    Sprint spr = SprintDetails.EditItem(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    TreeNode node = editTree(SprintDetails.GetInRelease());
                    node.Text = spr.Name;
                    node.Select();
                    break;
                }
            case 2:
                {
                    Release rel = ReleaseDetails.EditItem(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    TreeNode node = editTree(ReleaseDetails.SuperiorItemID);
                    node.Text  = rel.Name;
                    node.Select();
                    break;
                }
            case 1:
                {
                    Project proj = ProjectDetails.EditItem(System.Convert.ToInt32(treeData.SelectedNode.Value));
                    treeData.SelectedNode.Text = proj.Name;
                    break;
                }
            default:
                {
                    return;
                }
        }
        treeData.DataBind();
        treeData_SelectedNodeChanged(new Object(), new EventArgs());
    }

    private TreeNode editTree(int newParentNodeId)
    {
        TreeNode node = treeData.SelectedNode;
        TreeNode parent = treeData.SelectedNode.Parent;
        parent.ChildNodes.Remove(node);
        bool found = false;
        foreach (TreeNode t in parent.Parent.ChildNodes)
        {
            if (!found && t.Value.Equals(newParentNodeId.ToString()))
            {
                t.ChildNodes.Add(node);
                found = true;
            }
        }
        return node;
    }
}
